<template>
  <Card :bordered="false" dis-hover bordered>
    <Layout>
      <Header class="header-grids space-left-small">
        <Row>
          <Button size="default" type="primary" @click="addChildNode">添加子菜单</Button>
          <Button size="default" class="space-left" @click="addTopNode">添加顶部菜单</Button>
          <Button size="default" type="error" class="space-left" @click="openDeleteModal">批量删除</Button>
          <Dropdown @on-click="dispatchActions" class="space-left">
            <Button size="default" type="default">
              更多操作
              <Icon type="ios-arrow-down"></Icon>
            </Button>
            <DropdownMenu slot="list">
              <DropdownItem v-for="item in dropDownSelect" value="item.value" :name="item.value" :key="item.value">{{
                item.label }}
              </DropdownItem>
            </DropdownMenu>
          </Dropdown>
          <Switch size="large" class="space-left" v-model="isCascade">
            <span slot="open">级联</span>
            <span slot="close">单选</span>
          </Switch>
        </Row>
      </Header>
      <Layout>
        <Sider class="side-node space-left">
          <Row>
            <Alert style="height:40px" show-icon>当前选择编辑：
              <Button class="select-title text-btn" style="padding: 0 15px 0" size="large" v-text="checkedNode.name"
                      type="text">
              </Button>
            </Alert>
          </Row>
          <Row>
            <Input suffix="ios-search" placeholder="输入菜单名称搜索" width="100%" v-model="searchWord" @input="searchTree"/>
          </Row>
          <Row style="max-height: 348px;overflow-x:hidden; overflow-y:auto;">
            <Tree :data="menutree" ref="tree" show-checkbox :check-strictly="!isCascade"
                  @on-select-change="selectTreeMenu"
                  :render="renderContent"></Tree>
            <Spin size="large" fix v-if="spinShow"></Spin>
          </Row>
        </Sider>
        <Content class="space-left">
          <Row>
            <Form ref="formValidate" :model="formValidate" :rules="ruleValidate" :label-width="100">
              <FormItem label="类型">
                <Icon
                  :type="formValidate.level === 0 ? 'md-paper-plane': (formValidate.level === 1 || formValidate.level === 2)  ? 'md-reorder':formValidate.level ===3? 'md-radio-button-on':'ios-help-circle-outline'"></Icon>
                {{formValidate.level === 0 ? '顶级菜单': (formValidate.level === 1 || formValidate.level === 2) ? '页面菜单' :
                formValidate.level === 3 ? '按钮':'待定'}}
              </FormItem>
              <FormItem label="名称" prop="name">
                <Input v-model="formValidate.name" class="form-input-length" placeholder="输入菜单名称"/>
              </FormItem>
              <FormItem label="路由地址" prop="path">
                <Input v-model="formValidate.path" class="form-input-length" placeholder="输入路由地址"/>
              </FormItem>
              <FormItem label="路由英文名" prop="nameEn">
                <Input v-model="formValidate.nameEn" class="form-input-length" placeholder="输入路由英文名"/>
              </FormItem>
              <FormItem label="排序值" prop="sort">
                <InputNumber :max="10" :min="1" v-model="formValidate.sort"></InputNumber>
              </FormItem>
              <FormItem label="是否启用" prop="openFlag">
                <Switch size="large" v-model="formValidate.openFlag">
                  <span slot="open">启用</span>
                  <span slot="close">禁用</span>
                </Switch>
              </FormItem>
              <FormItem>
                <Button type="primary" @click="handleSubmit('formValidate')">修改并保存</Button>
                <Button @click="handleReset('formValidate')" style="margin-left: 8px">重置</Button>
              </FormItem>
            </Form>
          </Row>
        </Content>
      </Layout>
      <!--<Footer>提交、修改等按钮</Footer>-->
    </Layout>

    <!--子节点模态框-->
    <Modal loading closable v-model="childNodeModel" ref="childNodeModel" draggable scrollable title="添加子菜单(可拖动)">
      <Form ref="childForm" :model="childForm" :rules="ruleValidate" :label-width="100">
        <FormItem label="上级菜单名称">
          <Tag type="dot" color="primary">{{checkedNode.name}}</Tag>
        </FormItem>
        <FormItem label="类型" prop="level">
          <Select v-model="childForm.level" class="form-input-length" clearable>
            <Option :disabled="checkedNode.level >= 2"
                    :value="checkedNode.level === 0 ? '1' : checkedNode.level === 1 ? '2' : checkedNode.level === 2 ? '2' : '2'"
                    :key="checkedNode.level === 0 ? '1' : checkedNode.level === 1 ? '2' : checkedNode.level === 2 ? '2' : '2'">
              <i class="ivu-icon ivu-icon-md-reorder space-right"></i>页面菜单
            </Option>
            <Option value="3" :key="3" :disabled="checkedNode.level >= 3"><i
              class="ivu-icon ivu-icon-md-radio-button-on space-right"></i>按钮
            </Option>
          </Select>
        </FormItem>
        <FormItem label="名称" prop="name">
          <Input v-model="childForm.name" class="form-input-length" placeholder="输入菜单名称"/>
        </FormItem>
        <FormItem label="路由地址" prop="path">
          <Input v-model="childForm.path" class="form-input-length" placeholder="输入路由地址"/>
        </FormItem>
        <FormItem label="路由英文名" prop="nameEn">
          <Input v-model="childForm.nameEn" class="form-input-length" placeholder="输入路由英文名"/>
        </FormItem>
        <FormItem label="排序值" prop="sort">
          <InputNumber :max="10" :min="1" v-model="childForm.sort"></InputNumber>
        </FormItem>
        <FormItem label="是否启用" prop="openFlag">
          <Switch size="large" v-model="childForm.openFlag">
            <span slot="open">启用</span>
            <span slot="close">禁用</span>
          </Switch>
        </FormItem>
      </Form>
      <div slot="footer" style="margin-left: 340px;">
        <Button type="default" size="large" @click="childNodeCancel('childForm')">取消</Button>
        <Button type="primary" size="large" @click="childNodeOk('childForm')">提交</Button>
      </div>
    </Modal>

    <!--顶级节点模态框-->
    <Modal loading closable v-model="topNodeModel" ref="topNodeModel" draggable scrollable title="添加顶级菜单(可拖动)">
      <Form ref="topForm" :model="topForm" :rules="ruleValidate" :label-width="100">
        <FormItem label="类型">
          <Icon type="md-paper-plane"></Icon>
          顶层
        </FormItem>
        <FormItem label="系统代码" prop="syscode">
          <AutoComplete
            v-model="topForm.syscode"
            class="form-input-length"
            :data="sysList"
            :filter-method="filterMethod"
            placeholder="输入系统代码"
          >
          </AutoComplete>
        </FormItem>
        <FormItem label="名称" prop="name">
          <Input v-model="topForm.name" class="form-input-length" placeholder="输入菜单名称"/>
        </FormItem>
        <FormItem label="路由地址" prop="path">
          <Input v-model="topForm.path" class="form-input-length" placeholder="输入路由地址"/>
        </FormItem>
        <FormItem label="路由英文名" prop="nameEn">
          <Input v-model="topForm.nameEn" class="form-input-length" placeholder="输入路由英文名"/>
        </FormItem>
        <FormItem label="排序值" prop="sort">
          <InputNumber :max="10" :min="1" v-model="topForm.sort"></InputNumber>
        </FormItem>
        <FormItem label="是否启用" prop="openFlag">
          <Switch size="large" v-model="topForm.openFlag">
            <span slot="open">启用</span>
            <span slot="close">禁用</span>
          </Switch>
        </FormItem>
      </Form>
      <div slot="footer" style="margin-left: 340px;">
        <Button type="default" size="large" @click="topNodeCancel('topForm')">取消</Button>
        <Button type="primary" size="large" @click="topNodeOk('topForm')">提交</Button>
      </div>
    </Modal>
    <!--批量删除时的弹窗提示-->
    <Modal
      title="提示"
      v-model="deleteModal"
      class-name="vertical-center-modal">
      <p slot="header" style="color:#f60;text-align:center">
        <Icon type="ios-information-circle"></Icon>
        <span>删除提示</span>
      </p>
      <div style="text-align:center">
        <p>确定要删除选中的菜单节点及其下面的所有子菜单？
        </p>
      </div>
      <div slot="footer">
        <Button type="error" size="large" long @click="deleteNodes">确定</Button>
      </div>
    </Modal>
  </Card>


</template>

<script>
  import {addMenuNode, batchDeleteNodes, getMenuList, updateNode, getSysCodeList} from '@/api/menu'


  export default {
    name: 'menumgt',
    data() {
      return {
        spinShow: false,//Spin loading样式
        checkedNode: '',
        childNodeModel: false,
        topNodeModel: false,
        isCascade: true,//默认是级联  false 则代表单选
        //右侧表单
        formValidate: {
          name: '',
          path: '',
          nameEn: '',
          sort: 0,
          openFlag: false,
        },
        //添加子菜单 model
        childForm: {
          name: '',
          path: '',
          level: '',
          nameEn: '',
          sort: 0,
          openFlag: false,
        },
        //添加顶级菜单 model
        topForm: {
          name: '',
          path: '',
          syscode: '',
          nameEn: '',
          sort: 0,
          openFlag: false,
        },
        ruleValidate: {
          syscode: [
            {required: true, message: '系统代码不能为空', trigger: 'blur,change'}
          ],
          name: [
            {required: true, message: '名称不能为空', trigger: 'blur'}
          ],
          path: [
            {required: true, message: '路由地址不能为空', trigger: 'blur'},
          ],
          nameEn: [
            {required: true, message: '路由英文名不能为空', trigger: 'blur'}
          ],
          level: [
            {required: true, message: '菜单类型不能为空', trigger: 'blur'}
          ],
        },
        menutree: [],
        dropDownSelect: [
          {
            value: 'refresh',
            label: '刷新',
          },
          {
            value: 'rollall',
            label: '收合所有',
          },
          {
            value: 'openone',
            label: '仅展开一级'
          },
          {
            value: 'opentwo',
            label: '仅展开两级'
          },
          {
            value: 'openall',
            label: '展开所有'
          }
        ],
        deleteModal: false,
        checkedIds: [],
        searchWord: "",//菜单名称
        efficientSearchData: [],//提供深度搜索的数据
        expandLevel: "",
        sysList: [],
      }
    },
    methods: {
      initMenuNodes(menuname, level) {
        //查询level为1 的菜单列表
        this.spinShow = true;
        getMenuList({menuname, level}).then(res => {
          this.spinShow = false;
          const data = res.data;
          //重置选中值
          this.resetForm();
          this.menutree = [];
          this.menutree.push(...data);
          this.efficientSearchData = this.menutree;
        }).catch(err => {
          this.spinShow = false;
          console.error("获取菜单列表信息出错! " + err)
        })
      },
      initSysCodeList() {
        getSysCodeList().then(res => {
          const data = res.data;
          this.sysList = [];
          this.sysList.push(...data);
        }).catch(err => {
          console.error("获取系统代码出错")
        })
      },
      childNodeOk(name) {
        let childModal = this.$refs.childNodeModel;
        this.$refs[name].validate((valid) => {
          let menuNode = {
            title: this.childForm.name,
            parentId: this.checkedNode.id,
            syscode: this.checkedNode.syscode,
            name: this.childForm.name,
            path: this.childForm.path,
            level: this.childForm.level,
            nameEn: this.childForm.nameEn,
            sort: this.childForm.sort,
            openFlag: this.childForm.openFlag
          };
          if (valid) {
            addMenuNode(menuNode).then(res => {
              this.handleResult(res);
            }).catch(err => {
              this.spinShow = false;
              console.error("添加子菜单出错! " + err)
            });
            //over
            this.resetChildForm('childForm');
            childModal.close();
          } else {
            return false;
          }
        })

      },
      childNodeCancel(name) {
        this.$refs.childNodeModel.close();
      },
      topNodeOk(name) {
        let _that = this;
        let topModal = this.$refs.topNodeModel;
        this.$refs[name].validate((valid) => {
          let menuNode = {
            parentId: 0,
            title: this.topForm.name,
            name: this.topForm.name,
            syscode: this.topForm.syscode,
            path: this.topForm.path,
            level: 0,
            nameEn: this.topForm.nameEn,
            sort: this.topForm.sort,
            openFlag: this.topForm.openFlag
          };
          if (valid) {
            // this.appendTopNode(_that.menutree, topNode);
            addMenuNode(menuNode).then(res => {
              this.handleResult(res);
            }).catch(err => {
              this.spinShow = false;
              console.error("添加顶部菜单出错! " + err)
            });

            //结束
            this.resetTopForm('topForm');
            topModal.close();
          } else {
            return false;
          }
        })

      },
      topNodeCancel(name) {
        this.$refs.topNodeModel.close();
      },

      addChildNode() {
        //校验1： 不存在已选中的节点,提示
        if (!this.checkedNode) {
          this.$Message["warning"]({background: true, content: '请点击选择要修改的菜单节点'});
          return false;
        }
        //校验2： 只允许添加到 level等于3的按钮权限层级
        if (this.checkedNode.level === 3) {
          this.$Modal.warning({
            title: "提示",
            content: '不能添加啦，当前仅支持到按钮权限'
          });
          return false;
        }
        //重置
        this.resetTopForm('childForm');
        this.$refs['childForm'].resetFields();
        this.childNodeModel = true;
      },
      addTopNode() {
        //打开模态框
        this.resetTopForm('topForm');
        this.$refs.topForm.resetFields();
        this.topNodeModel = true;
      },
      handleSubmit(name) {
        let _that = this;
        if (!_that.checkedNode) {
          this.$Message["warning"]({background: true, content: '请点击选择要修改的菜单节点'});
          return false;
        }
        this.$refs[name].validate((valid) => {
          if (valid) {
            let menuNode = {
              id: _that.checkedNode.id,
              parentId: _that.checkedNode.parentId,
              level: _that.checkedNode.level,
              title: this.formValidate.title,
              name: this.formValidate.name,
              path: this.formValidate.path,
              nameEn: this.formValidate.nameEn,
              sort: this.formValidate.sort,
              openFlag: this.formValidate.openFlag
            };
            updateNode(menuNode).then(res => {
              let data = res.data;
              let message = data.message;
              let code = data.code;
              if (code === 200) {
                this.$Message.success(message);
                this.initMenuNodes(this.searchWord);
              }
              if (code === 500) {
                this.$Message["warning"]({background: true, content: message});
              }
            }).catch(err => {
              console.error("更新菜单菜单时出错!" + err)
            });
          }
        })
      },
      handleReset(name) {
        if (this.$refs[name] !== undefined) {
          this.$refs[name].resetFields();
          this.resetSelectedNode();
        }
      },
      selectTreeMenu(arr, data) {
        //变更提示信息中的数据
        this.$refs.formValidate.resetFields();
        this.renderForm(data);
        if (this.checkedNode.level === 3) {
          this.resetChildForm();
          this.childNodeModel = false;
        }
      },
      renderForm(data) {
        this.checkedNode = data;
        this.formValidate.name = data.name;
        this.formValidate.path = data.path;
        this.formValidate.nameEn = data.nameEn;
        this.formValidate.level = data.level;
        this.formValidate.sort = data.sort;
        this.formValidate.openFlag = data.openFlag;
      },
      resetSelectedNode() {
        if (this.checkedNode) {
          this.checkedNode.selected = false;
          this.checkedNode = "";
        }

      },
      resetForm() {
        this.checkedNode = "";
        this.formValidate.name = "";
        this.formValidate.path = "";
        this.formValidate.nameEn = "";
        this.formValidate.level = "";
        this.formValidate.sort = 0;
        this.formValidate.openFlag = false;
      },
      resetChildForm() {
        this.childForm.name = "";
        this.childForm.path = "";
        this.childForm.nameEn = "";
        this.childForm.level = "";
        this.childForm.sort = 0;
        this.childForm.openFlag = false;
      },
      resetTopForm() {
        this.topForm.name = "";
        this.topForm.path = "";
        this.topForm.nameEn = "";
        this.topForm.level = "";
        this.topForm.sort = 0;
        this.topForm.openFlag = false;
      },
      append(data, child) {
        const children = data.children || [];
        children.push({
          expand: true,
          title: child.name,
          name: child.name,
          path: child.path,
          nameEn: child.nameEn,
          level: child.level,
          sort: child.sort,
          openFlag: child.openFlag
        });
        this.$set(data, 'children', children);
      },
      appendTopNode(data, child) {
        //添加顶级元素
        data.push(child);
      },
      remove(root, node, data) {
        const parentKey = root.find(el => el === node).parent;
        const parent = root.find(el => el.nodeKey === parentKey).node;
        const index = parent.children.indexOf(data);
        parent.children.splice(index, 1);
      },
      openDeleteModal() {
        this.checkedIds = [];
        let checkedNodes = this.$refs.tree.getCheckedNodes();
        if (checkedNodes !== undefined && checkedNodes.length > 0) {
          checkedNodes.forEach((item, index) => {
            this.checkedIds.push(item.id);
          });
          this.deleteModal = true;
        } else {
          this.$Message["warning"]({background: true, content: "请先选择需要删除的菜单节点"});
        }
      },
      dispatchActions(name) {
        //请求分发
        switch (name) {
          case "refresh":
            this.refreshNodes();
            break;
          case "rollall":
            this.roll(this.menutree, 0);
            break;
          case "openone":
            this.roll(this.menutree, 1);
            break;
          case "opentwo":
            this.roll(this.menutree, 2);
            break;
          case "openall":
            this.roll(this.menutree, 3);
            break;
          default:
            this.$Message["info"]({background: true, content: '正在努力开发中...'});
            break;
        }

      },
      /**
       *  收合所有
       * @param treeNodes  当前的菜单树
       * @param type rollall openone opentwo openall
       */
      roll(treeNodes, type) {
        let _that = this;
        if (!!treeNodes) {
          treeNodes.forEach(node => {
            _that.expandLevel = node.level;
            //先收起所有节点
            node.expand = false;
            if (type === 0) {
              //收合所有
              node.expand = false;
            } else {
              if (_that.expandLevel > (type - 1)) {
                return;
              }
              //展开节点
              node.expand = true;
            }
            if (node.children && node.children.length > 0) {
              this.roll(node.children, type)
            }
          });
        }
        _that.expandLevel = "";
      },
      refreshNodes() {
        this.initMenuNodes(this.searchWord);
      },
      /**
       *  收合所有
       * @param treeNodes  当前的菜单树
       * @param type rollall openone opentwo openall
       */
      roll(treeNodes, type) {
        let _that = this;
        if (!!treeNodes) {
          treeNodes.forEach(node => {
            _that.expandLevel = node.level;
            //先收起所有节点
            node.expand = false;
            if (type === 0) {
              //收合所有
              node.expand = false;
            } else {
              if (_that.expandLevel > (type - 1)) {
                return;
              }
              //展开节点
              node.expand = true;
            }
            if (node.children && node.children.length > 0) {
              this.roll(node.children, type)
            }
          });
        }
        _that.expandLevel = "";
      },
      renderContent(h, {root, node, data}) {
        let level = node.node.level;
        return h('span', {
          style: {
            display: 'inline-block',
            width: '100%'
          }
        }, [
          h('span', [
            h('Icon', {
              props: {
                type: level === 0 ? 'md-paper-plane' : level === 1 || level === 2 ? 'md-reorder' : level === 3 ? 'md-radio-button-on' : 'ios-help-circle-outline'
              },
              style: {
                marginRight: '8px'
              }
            }),
            h('span',
              {
                style: {
                  display: "inline-block",
                  cursor: "pointer",
                  background: node.node.selected ? "#d5e8fc" : "#fff", //根据选中状态设置样式
                  color: node.node.selected ? "#515a6e" : "#515a6e",
                  borderRadius: "3px",
                  padding: "3px"
                },
                on: {
                  click: () => {
                    if (!node.node.selected)
                      this.$refs.tree.handleSelect(node.nodeKey); //手动选择树节点
                  }
                }
              }, data.title)
          ])

        ]);
      },
      handleResult(res) {
        let data = res.data;
        let message = data.message;
        let code = data.code;
        if (code === 200) {
          this.$Message.success(message);
          this.initMenuNodes(this.searchWord);
        }
        if (code === 500) {
          this.$Message["warning"]({background: true, content: message});
        }
      },
      deleteNodes() {
        //有节点选中
        if (this.checkedIds && this.checkedIds.length > 0) {
          batchDeleteNodes(this.checkedIds.join(",")).then(res => {
            this.handleResult(res);
          }).catch(err => {
            console.error("批量删除时出现异常:" + err)
          });
          this.deleteModal = false;
        }
      },
      searchTree() {
        this.initMenuNodes(this.searchWord);
        // this.keys = [];
        // this.efficientSearch();
      },
      efficientSearch: function () {
        let self = this;
        if (!self.menutree) {
          return
        }
        if (!self.searchWord) {
          this.initMenuNodes(this.searchWord);
        }
        let final = self.variableDeepSearch(self.efficientSearchData, [], self.searchWord); // 返回符合条件的对象
        if (final) {
          self.menutree = [];
          self.menutree = final
        } else {
          self.menutree = []
        }


      },
      variableDeepSearch: function (treeDataFilter, childTemp, searchWord) {
        let that = this;
        for (let i = 0; i < treeDataFilter.length; i++) {
          let item = treeDataFilter[i];
          if (item.title === searchWord) {
            if (childTemp.length === 0) {
              item.expand = true;
              childTemp.push(item);
            }
            return childTemp;
          }
          if (item.children && item.children.length > 0) {
            // item.expand = true;
            childTemp.push(item);
            let rs = that.variableDeepSearch(item.children, childTemp, searchWord);
            if (rs) {
              return rs;
            } else {
              let index = childTemp.indexOf(item);
              if (index > -1) {
                childTemp.splice(index, 1);
              }
            }
          }
        }
      },
      filterMethod(value, option) {
        return option.toUpperCase().indexOf(value.toUpperCase()) !== -1;
      }

    },
    mounted() {
      this.initMenuNodes(this.searchWord);
      this.initSysCodeList();
    }
  }
</script>

<style lang="less">
  @import 'index.less';
</style>
